home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / simula / books / books.lha / kirkerud / studchain2.sim < prev    next >
Text File  |  1993-08-16  |  17KB  |  427 lines

  1. % ****************************************************************
  2. % *                                                              *
  3. % *  This is a revised version of the program constructed in     *
  4. % *  section 14.3 of                                             *
  5. % *  Object Oriented Programming with Simula by Bj|rn Kirkerud;  *
  6. % *  The revisions in the program consist in the use of          *
  7. % *  a few classes containing generally useful tools             * 
  8. % *                                                              *
  9. % ****************************************************************
  10.  
  11.  
  12. begin
  13.  
  14. % ****************************************************************
  15. % *                                                              *
  16. % *  Declarations of classes containing generally usefull tools: *
  17. % *                                                              *
  18. % ****************************************************************
  19.  
  20.   external class promptools, texttools, filetools;
  21.  
  22.   ref(promptools) pt;
  23.   ref(texttools)  tt;
  24.   ref(filetools)  ft;
  25.  
  26.   procedure outline(line); text line;
  27.     begin outtext(line); outimage end;
  28.  
  29.  
  30. % ****************************************************************
  31. % *                                                              *
  32. % *  The class Student:                                          *
  33. % *                                                              *
  34. % ****************************************************************
  35.  
  36.   class Student;
  37.     begin
  38.  
  39.     ! Variables to keep the data that describe this student:   ;
  40.  
  41.       integer ident, year, month, day, form;
  42.       Boolean female;
  43.       character math_grade, eng_grade, hist_grade;
  44.  
  45.  
  46.     ! A procedure with a value which is unique for this student:  ;
  47.  
  48.       text procedure key; 
  49.         key :- tt.int_as_text(ident);
  50.  
  51.  
  52.     ! A variable to hold a reference to the next Student in a pointer chain:   ;
  53.  
  54.       ref(Student) next_in_chain;
  55.  
  56.  
  57.     ! Data access procedures:   ;
  58.  
  59.       procedure read;
  60.         begin
  61.           ident         := pt.ask_for_int("Identity number? ");
  62.           year          := pt.ask_for_int("Year of birth? ");
  63.           month      := pt.ask_for_int("Month? ");
  64.           day          := pt.ask_for_int("Day? ");
  65.           form          := pt.ask_for_int("Form? ");
  66.           female     := pt.ask_for_bool("Female? ");
  67.           math_grade := pt.ask_for_char("Grade in mathematics? ");
  68.           eng_grade  := pt.ask_for_char("Grade in English? ");
  69.           hist_grade := pt.ask_for_char("Grade in history? ");
  70.         end of Student'read;
  71.  
  72.       procedure write;
  73.         begin
  74.           outtext("Data for student: "); outint(ident, 6);
  75.           outtext(".  Born: ");    
  76.              outint(day,   2); outchar('/');
  77.              outint(month, 2); outchar('/');
  78.              outint(year,  4);
  79.           outline(if female then ".  Female."  else ".  Male.");
  80.           outline("  Form: " & tt.int_as_text(form) & "." &
  81.                   "  Current grades:" &
  82.                   "  Mathematics: "   & tt.char_as_text(math_grade) &
  83.                   "  English: "       & tt.char_as_text(eng_grade) &
  84.                   "  History: "       & tt.char_as_text(hist_grade));
  85.         end of Student'write;
  86.  
  87.       procedure change;
  88.         begin character attribute;
  89.           attribute := pt.ask_for_char("What do you want  to change? ");
  90.           if attribute = 'i' then ident      
  91.              := pt.ask_for_int("New identity number? ")    else
  92.           if attribute = 'y' then year       
  93.              := pt.ask_for_int("New birth year? ")       else
  94.           if attribute = 'm' then month      
  95.              := pt.ask_for_int("New birth month? ")        else
  96.           if attribute = 'd' then day        
  97.              := pt.ask_for_int("New day of birth? ")       else
  98.           if attribute = 'f' then form       
  99.              := pt.ask_for_int("New form number? ")        else
  100.           if attribute = 's' then female     
  101.              := pt.ask_for_bool("Female? ")                else
  102.           if attribute = 'a' then math_grade 
  103.              := pt.ask_for_char("New grade in  math? ")    else
  104.           if attribute = 'e' then eng_grade  
  105.              := pt.ask_for_char("New grade in  English? ") else
  106.  
  107.           if attribute = 'h' then hist_grade 
  108.              := pt.ask_for_char("New grade in  history? ")
  109.         else begin
  110.               outline("You can change one of the  following attributes:");
  111.               outline("  i: Identity number");  
  112.               outline("  y: Birth year");
  113.               outline("  m: Birth month");    
  114.               outline("  d: Day of birth");
  115.               outline("  f: Form number");    
  116.               outline("  s: Sex");
  117.               outline("  a: Grade in mathematics");
  118.               outline("  e: Grade in English");
  119.               outline("  h: Grade in history");
  120.               change; ! Observe that this is an invocation of the procedure 
  121.                       ! being declared. The effect is that user is given
  122.                       ! another chance to change;
  123.             end;
  124.         end of Student'change;
  125.  
  126.       character procedure worst_grade;
  127.         worst_grade := max(math_grade, max(eng_grade,  hist_grade));
  128.  
  129.       procedure put_in_record(outf); ref(outfile) outf;
  130.         begin
  131.           ft.int_to_file(outf, ident);
  132.           ft.int_to_file(outf, year); 
  133.           ft.int_to_file(outf, month); 
  134.           ft.int_to_file(outf, day); 
  135.           ft.int_to_file(outf, form); 
  136.           ft.bool_to_file(outf, female);
  137.           outf.outchar(math_grade); 
  138.           outf.outchar(eng_grade); 
  139.           outf.outchar(hist_grade); 
  140.         end;
  141.  
  142.       procedure get_from_record(inf); ref(infile) inf;
  143.         begin
  144.           ident      := ft.int_from_file(inf);
  145.           year       := ft.int_from_file(inf); 
  146.           month      := ft.int_from_file(inf); 
  147.           day        := ft.int_from_file(inf); 
  148.           form       := ft.int_from_file(inf); 
  149.           female     := ft.bool_from_file(inf); 
  150.           math_grade := inf.inchar; 
  151.           eng_grade  := inf.inchar; 
  152.           hist_grade := inf.inchar; 
  153.         end;
  154.  
  155.     end of Student;
  156.  
  157.  
  158. % ****************************************************************
  159. % *                                                              *
  160. % *  The class School:                                           *
  161. % *                                                              *
  162. % ****************************************************************
  163.  
  164.   class School;
  165.       protected first_in_chain, last_in_traversal;
  166.     begin
  167.  
  168.     ! Declaration of a variable to hold a reference to the first Student  
  169.     ! in the pointer chain:  ;
  170.  
  171.       ref(Student) first_in_chain;
  172.  
  173.  
  174.     ! Declaration of a variable to hold a reference to the Student
  175.     ! last vistited in a traversal of the chain:  ;
  176.  
  177.       ref(Student) last_in_traversal;
  178.  
  179.  
  180.     ! Declarations of data access procedures:   ;
  181.  
  182.       procedure Place_student(a_student, student_exists);
  183.           name student_exists; ref(Student) a_student;  Boolean student_exists;
  184.         begin
  185.           student_exists := false;
  186.           if first_in_chain == none
  187.             then first_in_chain :- a_student    
  188.                   ! The new object is placed first;
  189.           else if a_student.key < first_in_chain.key
  190.             then begin
  191.               a_student.next_in_chain :- first_in_chain;
  192.               first_in_chain :- a_student;       
  193.                   ! The new object is placed first;
  194.             end
  195.           else begin ref(Student) aux_stud;  Boolean aux_found;
  196.               aux_stud :- first_in_chain;  aux_found := false;
  197.               while not aux_found do
  198.                 if aux_stud.next_in_chain == none  then aux_found := true
  199.                 else if a_student.key <  aux_stud.next_in_chain.key  
  200.                      then aux_found := true
  201.                 else aux_stud :- aux_stud.next_in_chain;
  202.               if a_student.key = aux_stud.key
  203.                 then student_exists := true
  204.                 else begin
  205.                     a_student.next_in_chain :- aux_stud.next_in_chain;
  206.                     aux_stud.next_in_chain  :- a_student;    
  207.                       ! The new object is placed after aux_stud;
  208.                   end;
  209.             end;
  210.         end of Place_student;
  211.  
  212.       ref(Student) procedure find_student(key);  text key;
  213.           ! This version assumes that the pointer chain is sorted  
  214.           ! on increasing key-values;
  215.         begin ref(Student) aux_stud; Boolean found;
  216.           aux_stud :- first_in_chain;
  217.           while aux_stud =/= none and not found do
  218.             if aux_stud.key > key then aux_stud :- none else
  219.             if aux_stud.key = key then found := true
  220.             else aux_stud :- aux_stud.next_in_chain;
  221.           find_student :- aux_stud;
  222.         end of find_student;
  223.  
  224.       ref(Student) procedure first_student;
  225.         begin 
  226.           first_student :- first_in_chain;  
  227.           last_in_traversal :- first_in_chain;
  228.         end;
  229.  
  230.       ref(Student) procedure next_student;
  231.         if last_in_traversal == none then next_student :- none
  232.         else begin
  233.             last_in_traversal :- last_in_traversal.next_in_chain;
  234.             next_student      :- last_in_traversal;
  235.           end;
  236.  
  237.       procedure Remove_specified_student(key, no_such_student);
  238.           name no_such_student; text key;  Boolean no_such_student;
  239.         begin  ref(Student) aux_stud, pred_stud; Boolean found;
  240.           aux_stud :- first_in_chain;
  241.           while aux_stud =/= none and not found do
  242.             if aux_stud.key = key then found := true
  243.             else begin
  244.               pred_stud :- aux_stud;
  245.               aux_stud  :- aux_stud.next_in_chain;
  246.             end;
  247.           if aux_stud == none then no_such_student := true
  248.           else begin
  249.             no_such_student := false;
  250.             if pred_stud == none
  251.               then first_in_chain          :- first_in_chain.next_in_chain
  252.               else pred_stud.next_in_chain :- aux_stud.next_in_chain;
  253.           end;
  254.         end of Remove_student;
  255.  
  256.     end of School;
  257.  
  258.  
  259. % ****************************************************************
  260. % *                                                              *
  261. % *   Start of School-context:                                   *
  262. % *                                                              *
  263. % ****************************************************************
  264.  
  265.   School begin
  266.  
  267.  
  268. % ****************************************************************
  269. % *                                                              *
  270. % *  Declarations of command procedures:                         *
  271. % *                                                              *
  272. % ****************************************************************
  273.  
  274.       procedure Give_help;
  275.         begin
  276.           outline("The legal commands are: "); 
  277.           outline("   ?:  Help (writes this text)"); 
  278.           outline("   N:  To enter data about a new student"); 
  279.           outline("   W:  Writes data about a specified student"); 
  280.           outline("   L:  Writes a list with all students"); 
  281.           outline("   C:  Changes data about a specified student"); 
  282.           outline("   R:  Removes all data about a specified student"); 
  283.           outline("   P:  Puts all data to file ""stud.dta"""); 
  284.           outline("   G:  Gets data from file ""stud.dta"""); 
  285.           outline("   B:  Writes students with bad grades"); 
  286.           outline("   Q:  Quit (the program execution stops)"); 
  287.         end of Give_help;
  288.  
  289.       procedure Enter_student;
  290.         begin  ref(Student) a_student; Boolean ident_exists;
  291.           a_student :- new Student;
  292.           a_student.read;
  293.           Place_student(a_student, ident_exists);
  294.           if ident_exists
  295.             then outline("The identity number is already  in use!")
  296.             else outline("The data have been stored.");
  297.         end of Enter_student;
  298.  
  299.       procedure Write_student;
  300.         begin integer ident_number; ref(Student) a_student;
  301.           ident_number := pt.ask_for_int("Identity number? ");
  302.           a_student    :- find_student(tt.int_as_text(ident_number));
  303.           if a_student == none
  304.             then outline("No student with that  identity number!")
  305.             else a_student.write;
  306.         end of Write_student;
  307.  
  308.       procedure List_students;
  309.         begin ref(Student) a_student;
  310.           outline("The students for which data have  been entered:");
  311.           a_student :- first_student;
  312.           while a_student =/= none do
  313.             begin a_student.write;  a_student :- next_student end;
  314.         end of List_students;
  315.  
  316.       procedure Change_student;
  317.         begin ref(Student) a_student; integer ident_number;
  318.           ident_number := pt.ask_for_int("Identity number? ");
  319.           a_student :- find_student(tt.int_as_text(ident_number));
  320.           if a_student == none
  321.             then outline("No student with that  identity number!")
  322.             else begin a_student.write;  a_student.change end;
  323.         end of Change_student;
  324.  
  325.       procedure Remove_student;
  326.         begin integer ident_number;  Boolean no_such_student;
  327.           ident_number := pt.ask_for_int("Identity number? ");
  328.           Remove_specified_student(tt.int_as_text(ident_number),  no_such_student);
  329.           if no_such_student
  330.             then outline("No student with that identity  number!")
  331.             else outline("The student has been removed!");
  332.         end of Remove_student;
  333.  
  334.       procedure Put_to_file;
  335.         inspect new outfile("stud.dta") do
  336.           begin ref(Student) a_student;
  337.             open(blanks(24));
  338.             a_student :- first_student;
  339.             while a_student =/= none do
  340.               begin
  341.                 a_student.put_in_record(this outfile);
  342.                 outimage;
  343.                 a_student :- next_student;
  344.               end;
  345.             close;
  346.           end;
  347.  
  348.       procedure Get_from_file;
  349.         inspect new infile("stud.dta") do
  350.           if open(blanks(24)) 
  351.             then begin ref(Student) a_student; Boolean ident_exists;
  352.               inimage;
  353.               while not endfile do
  354.                 begin
  355.                   a_student :- new Student;
  356.                   a_student.get_from_record(this infile);
  357.                   Place_student(a_student, ident_exists);
  358.                   inimage;
  359.                 end;
  360.               close;
  361.             end
  362.           else outline("File stud.dta can not be opened for reading");
  363.  
  364.       procedure Bad_grades;
  365.         begin character grade_limit;  ref(Student) a_student;
  366.           grade_limit := pt.ask_for_char("Grade limit? ");
  367.           a_student :- first_student;
  368.           while a_student =/= none do
  369.             begin
  370.               if a_student.worst_grade ge grade_limit then a_student.write;
  371.               a_student :- next_student;
  372.             end;
  373.         end of Bad_grades;
  374.  
  375.  
  376.       procedure Unknown_command(c); character c;
  377.         begin
  378.           outline("   You gave the command '" & tt.char_as_text(c) & "'" &
  379.                   "   This is not among the legal commands.");
  380.           outline("   Type ? if you don't remember the legal commands"); 
  381.         end of Unknown command;
  382.  
  383.  
  384. % ****************************************************************
  385. % *                                                              *
  386. % *  Declaration of a variable to keep the latest command        *
  387. % *  typed by the user:                                          *
  388. % *                                                              *
  389. % ****************************************************************
  390.  
  391.   character command;
  392.  
  393.  
  394. % ****************************************************************
  395. % *                                                              *
  396. % *  That was the last declaration.                              *
  397. % *  Now come the imperatives of the program:                    *
  398. % *                                                              *
  399. % ****************************************************************
  400.  
  401.   pt :- new promptools;
  402.   tt :- new texttools;
  403.   ft :- new filetools;
  404.  
  405.  
  406.   command := pt.ask_for_char("Type your first command  (? for help) > ");
  407.   while command ne 'Q' do
  408.     begin
  409.       if command = '?' then Give_help         else
  410.       if command = 'N' then Enter_student  else
  411.       if command = 'W' then Write_student  else
  412.       if command = 'L' then List_students  else
  413.       if command = 'C' then Change_student else
  414.       if command = 'R' then Remove_student else
  415.       if command = 'P' then Put_to_file    else
  416.       if command = 'G' then Get_from_file  else
  417.       if command = 'B' then Bad_grades
  418.       else Unknown_command(command);
  419.       command := pt.ask_for_char("Your next command > ");
  420.     end;
  421.  
  422.   outline("Bye");
  423.  
  424. end of block prefixed by School;
  425.  
  426. end
  427.